package com.mju.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mju.controller.common.JsonResult;
import com.mju.dao.OrderDao;
import com.mju.dao.OrderItemDao;
import com.mju.feign.clients.*;
import com.mju.pojo.*;
import com.mju.pojo.vo.CartVO;
import com.mju.service.ex.DeleteException;
import com.mju.service.ex.InsertException;
import com.mju.service.ex.UpdateException;
import com.mju.utils.BeanCopyUtils;
import com.mju.vo.OrderVo;
import com.sun.org.apache.bcel.internal.generic.ACONST_NULL;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Array;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderItemDao orderItemDao;

    // 需要调用收货地址业务层的getByAid方法
    @Autowired
    private AddressClient addressClient;

    // 需要调用购物车业务层的getVOByCids方法
    @Autowired
    private CartClient cartClient;

    //// 需要调用用户业务层的getByUid方法
    @Autowired
    private UserClient userClient;

    @Autowired
    private ProductClient productClient;

    // 需要调用发起退款接口
    @Autowired
    private RefundInfoClient refundInfoClient;

    
    @Override
    public Order createOrder(Integer aid, Integer[] cids, Integer uid, String username) {
        //返回的列表中的对象都是即将下单的
        JsonResult<List<CartVO>> cartVoData = cartClient.selectVOByCidsAndUid(uid, cids);
        List<CartVO> list = cartVoData.getData();
        System.out.println("list:" + list);
        // 计算本订单中的商品总价
        double totalPrice = 0L;
        for (CartVO cartVO : list) {
            totalPrice += cartVO.getRealPrice()*cartVO.getNum();
        }

        // 判断用户是否是vip，是就88折
        JsonResult<User> data = userClient.getById(uid);
        User user = data.getData();
        Integer isVip = user.getIsVip();
        System.out.println("isVip:" + isVip);
        if (isVip == 1) {
            totalPrice = totalPrice * 0.88;
        }

        // 获取Address数据
        JsonResult<Address> addressData = addressClient.getById(uid, aid);
        Address address = addressData.getData();
        System.out.println("address:" + address);
        Order order = new Order();
        order.setUid(uid);

        //封装收货地址
        order.setAid(address.getId());
        order.setRecvName(address.getName());
        order.setRecvPhone(address.getPhone());
        order.setRecvProvince(address.getProvinceName());
        order.setRecvCity(address.getCityName());
        order.setRecvArea(address.getAreaName());
        order.setRecvAddress(address.getAddress());

        //封装创建时间,支付状态和总价
        order.setOrderTime(new Date());
        order.setStatus(0); // 0: 未支付
        order.setTotalPrice(totalPrice);

        //封装四个日志
        order.setCreatedUser(username);
        order.setCreatedTime(new Date());
        order.setModifiedUser(username);
        order.setModifiedTime(new Date());

        // 插入订单数据
        int rows = orderDao.insert(order);
        if(rows != 1) {
            throw new InsertException("插入数据时产生未知的异常");
        }

        // 插入订单的所有商品的详细数据
        for(CartVO cartVO: list) {
            // 创建订单项
            OrderItem orderItem = new OrderItem();
            // 封装数据
            orderItem.setOid(order.getOid()); // 主键自增

            orderItem.setPid(cartVO.getPid());
            orderItem.setTitle(cartVO.getTitle());
            orderItem.setImage(cartVO.getImage());
            orderItem.setPrice(cartVO.getRealPrice());
            orderItem.setNum(cartVO.getNum());

            orderItem.setCreatedUser(username);
            orderItem.setCreatedTime(new Date());
            orderItem.setModifiedUser(username);
            orderItem.setModifiedTime(new Date());

            rows = orderItemDao.insert(orderItem);
            if (rows != 1) {
                throw new InsertException("插入数据时产生未知的异常");
            }
        }
        return order;
    }

    @Override
    public Integer createOrderItem(Integer oid, Integer cid, Integer num, String username) {
        //根据cid查询购物车的一条数据获取pid
        JsonResult<Cart> cartData = cartClient.queryCartByCid(cid);
        Cart cart = cartData.getData();
        //取出pid的值
        Integer pid = cart.getPid();

        //根据pid查询商品信息
        JsonResult<Product> productData = productClient.getById(pid);
        Product product = productData.getData();
        //创建一个用于向持久层传输的OrderItem实体类对象
        OrderItem orderItem = new OrderItem();

        //补全orderItem对象的空白字段
        orderItem.setOid(oid);
        orderItem.setPid(pid);
        orderItem.setTitle(product.getTitle());
        orderItem.setImage(product.getImage());
        orderItem.setPrice(product.getPrice());
        orderItem.setNum(num);
        Date createdTime = new Date();
        orderItem.setCreatedUser(username);
        orderItem.setCreatedTime(createdTime);
        orderItem.setModifiedUser(username);
        orderItem.setModifiedTime(createdTime);

        //调用持久层进行插入
        int result = orderItemDao.insert(orderItem);

        if (result == 0){
            throw new InsertException("服务器出现错误，创建订单失败");
        }

        return result;
    }

    @Override
    public List<OrderVo> queryOrderVoByOid(Integer oid) {
        List<OrderVo> orderVos = orderDao.queryOrderVoByOid(oid);
        for (OrderVo vo: orderVos) {
            //根据每个订单的aid查询地址信息
            //Address address = addressService.queryAddressByAid(vo.getAid());
            JsonResult<Address> addressData = addressClient.getAddress(vo.getAid());
            Address address = addressData.getData();
            //补全OrderVo值对象中的空白字段
            vo.setZip(address.getZip());
            vo.setPhone(address.getPhone());
            vo.setProvinceName(address.getProvinceName());
            vo.setCityName(address.getCityName());
            vo.setAreaName(address.getAreaName());
            vo.setAddress(address.getAddress());
        }
        return orderVos;
    }


    @Override
    public List<OrderVo> queryOrderVoByUid(Integer uid) {
        List<OrderVo> orderVos = orderDao.queryOrderVoByUid(uid);
        for (OrderVo vo: orderVos) {
            //根据每个订单的oid查询地址信息
            //Address address = addressService.queryAddressByAid(vo.getAid());
            JsonResult<Address> addressData = addressClient.getAddress(vo.getAid());
            Address address = addressData.getData();
            //补全OrderVo值对象中的空白字段
            vo.setZip(address.getZip());
            vo.setPhone(address.getPhone());
            vo.setProvinceName(address.getProvinceName());
            vo.setCityName(address.getCityName());
            vo.setAreaName(address.getAreaName());
            vo.setAddress(address.getAddress());
        }
        return orderVos;
    }

    @Override
    public List<OrderVo> queryOrderVoByUname(String uname) {
        JsonResult<Integer> data = userClient.getUidByUname(uname);
        Integer uid = data.getData();
        return this.queryOrderVoByUid(uid);
    }

    @Override
    public List<Order> queryOrderByUid(Integer uid) {
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Order::getUid, uid).orderByAsc(Order::getOid);
        List<Order> orders = orderDao.selectList(lqw);
        return orders;
    }

    @Override
    public Boolean updateStatusByOid(Integer oid,Integer status) {
        Order order = orderDao.selectById(oid);
        order.setStatus(status);
        return orderDao.updateById(order)>0;
    }

    @Override
    public IPage<Order> queryAllOrderInfo(Integer currentPage, Integer pageSize) {
        IPage page = new Page<>(currentPage, pageSize);
        orderDao.selectPage(page,null);
        return page;
    }

    @Override
    public IPage<Order> conQueryAllOrderInfo(Integer currentPage, Integer pageSize, Order order) {
        IPage page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Order> lwq=new LambdaQueryWrapper<>();
        lwq.eq(!Objects.isNull(order.getOid()), Order::getOid, order.getOid());
        lwq.eq(!Objects.isNull(order.getUid()), Order::getUid, order.getUid());
        lwq.like(Strings.isNotEmpty(order.getRecvName()),Order::getRecvName,order.getRecvName());
        lwq.eq(Strings.isNotEmpty(order.getRecvPhone()),Order::getRecvPhone,order.getRecvPhone());
        lwq.eq(!Objects.isNull(order.getStatus()), Order::getStatus, order.getStatus());
        orderDao.selectPage(page,lwq);
        return page;
    }

    @Override
    public List<OrderVo> queryOrderItemByOid(Integer oid) {
        // 根据oid，获取相同oid的多个子订单项目
        LambdaQueryWrapper<OrderItem> lqw = new LambdaQueryWrapper<>();
        lqw.eq(OrderItem::getOid, oid);

        List<OrderItem> orderItems = orderItemDao.selectList(lqw);
        List<OrderVo> orderVos = new ArrayList<>();
        for (OrderItem orderItem : orderItems) {
            OrderVo orderVo = new OrderVo();
            orderVo.setOid(oid);
            orderVo.setTitle(orderItem.getTitle());
            orderVo.setImage(orderItem.getImage());
            orderVo.setPrice(orderItem.getPrice());
            orderVo.setNum(orderItem.getNum());
            orderVo.setTotalPrice(orderItem.getPrice() * orderItem.getNum());
            // 获取订单状态，并设置到vo类中
            Order order = orderDao.selectById(oid);
            orderVo.setStatus(order.getStatus());

            orderVo.setAid(order.getAid());
            orderVo.setRecvName(order.getRecvName());
            orderVo.setPhone(order.getRecvPhone());
            orderVo.setAddress(order.getRecvAddress());
            orderVo.setOrderTime(order.getOrderTime());
            orderVo.setPayTime(order.getPayTime());
            // 设置邮政编码
            Integer aid = order.getAid();
            JsonResult<Address> data = addressClient.getAddress(aid);
            Address address = data.getData();
            orderVo.setZip(address.getZip());

            // 加到orderVos中
            orderVos.add(orderVo);
        }
        return orderVos;
    }

    @Override
    public Integer deleteOrderByOid(Integer oid) {
        // 删除订单项
        LambdaQueryWrapper<OrderItem> lqw = new LambdaQueryWrapper<>();
        lqw.eq(OrderItem::getOid, oid);
        List<OrderItem> orderItems = orderItemDao.selectList(lqw);
        for (OrderItem orderItem : orderItems) {
            int rows = orderItemDao.deleteById(orderItem.getId());
            if(rows!=1) {
                throw new DeleteException("删除订单项异常");
            }
        }
        // 删除订单
        int rows = orderDao.deleteById(oid);
        if(rows!=1) {
            throw new DeleteException("删除订单异常");
        }
        return rows;
    }

    @Override
    public Order queryOrderByOid(Integer oid) {
        Order order = orderDao.selectById(oid);
        return order;
    }

    @Override
    public List<List<OrderVo>> queryAllOrderAndOrderItem(Integer uid) {
        List<Order> orders = queryOrderByUid(uid);
        List<List<OrderVo>> orderItems = new ArrayList<>();
        // 遍历订单信息
        for (Order order:
             orders) {
            Integer oid = order.getOid();
            System.out.println(oid);
            // 根据oid获取对应的OrderVo
            List<OrderVo> orderVos = queryOrderItemByOid(oid);
            orderItems.add(orderVos);
        }
        return orderItems;
    }

    @Override
    public List<List<OrderVo>> queryOrderByStatus(Integer uid, Integer status) {
        List<Order> orders = queryOrderByUid(uid);

        List<List<OrderVo>> orderItems = new ArrayList<>();
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Order::getStatus, status);

        List<Order> newOrder = orderDao.selectList(lqw);
        // 遍历订单信息
        for (Order order:
                newOrder) {
            Integer oid = order.getOid();
            System.out.println(oid);
            // 根据oid获取对应的OrderVo
            List<OrderVo> orderVos = queryOrderItemByOid(oid);
            orderItems.add(orderVos);
        }
        return orderItems;
    }

    @Override
    public List<List<OrderVo>> queryOrderByTitle(Integer uid, String title) {
        List<Order> orders = queryOrderByUid(uid);
        List<List<OrderVo>> orderItems = new ArrayList<>();

        LambdaQueryWrapper<OrderItem> lqw = new LambdaQueryWrapper<>();
        lqw.like(OrderItem::getTitle, title);

        List<OrderItem> oldOrderItemList = orderItemDao.selectList(lqw);
        List<OrderItem> newOrderItemList = new ArrayList<>();
        List<Order> newOrder = new ArrayList<>();
        // 对orderItemList去重，根据oid
        for (OrderItem orderItem : oldOrderItemList) {
            boolean flag = false;
            if(!newOrderItemList.isEmpty()) { // 非空，进行字段匹配
                for (OrderItem item : newOrderItemList) {
                    if(orderItem.getOid().equals(item.getOid())) { // 若oid有相同的
                        flag = true;
                    }
                }
            }
            if(!flag) { // 去重
                newOrderItemList.add(orderItem);
            }
        }

        // 变为Order
        for (OrderItem orderItem : newOrderItemList) {
            Integer oid = orderItem.getOid();
            // 根据oid获取order对象
            Order order = orderDao.selectById(oid);
            newOrder.add(order);
        }

        // 遍历订单信息
        for (Order order:
                newOrder) {
            Integer oid = order.getOid();
            System.out.println(oid);
            // 根据oid获取对应的OrderVo
            List<OrderVo> orderVos = queryOrderItemByOid(oid);
            orderItems.add(orderVos);
        }
        System.out.println(orderItems);
        return orderItems;
    }

    //@Override
    //public List<List<OrderVo>> queryOrderByTitle(Integer uid, String title) {
    //    List<Order> orders = queryOrderByUid(uid);
    //    List<List<OrderVo>> tempOrderItems = new ArrayList<>();
    //    List<List<OrderVo>> newOrderItems = new ArrayList<>();
    //
    //    orderItemDao.selectList(new LambdaQueryWrapper<>()
    //            .like(OrderItem::getTitle,title).groupBy()
    //    )
    //
    //    //for(Order order: orders) {
    //    //    Integer oid = order.getOid();
    //    //    // 获取对应的OrderVo对象
    //    //    List<OrderVo> orderVos = queryOrderItemByOid(oid);
    //    //    tempOrderItems.add(orderVos);
    //    //}
    //    //// 对tempOrderItems里边的每一个列表进行过滤
    //    //LambdaQueryWrapper<OrderItem> lqw = new LambdaQueryWrapper();
    //    //lqw.like(OrderItem::getTitle, title);
    //    //
    //    //List<OrderItem> orderItems = orderItemDao.selectList(
    //    //        new LambdaQueryWrapper<OrderItem>()
    //    //                .like(OrderItem::getTitle, title)
    //    //);
    //    //System.out.println(orderItemList);
    //    //List<OrderVo> orderVos = BeanCopyUtils.copyBeanList(orderItems, OrderVo.class);
    //    //List<List<OrderVo>> orderVOList = orderItemList.stream().map(
    //    //        orderItems -> {
    //    //            List<OrderVo> orderVOs = new ArrayList<>();
    //    //            System.out.println(orderItems);
    //    //            orderVOs.add(BeanCopyUtils.copyBean(orderItems, OrderVo.class));
    //    //            return orderVOs;
    //    //        }
    //    //).collect(Collectors.toList());
    //    //
    //    //System.out.println(orderVOList);
    //    //return  orderVOList;
    //    //orderItemList.stream().map(
    //    //        orderItems -> {
    //    //            List<OrderVo> orderVOs = new ArrayList<>();
    //    //            orderVOs.add(BeanCopyUtils.copyBean(orderItems, OrderVo.class));
    //    //            return orderVOs;
    //    //        }
    //    //).collect(Collectors.toList())
    //}

    //@Override
    //public List<OrderVo> queryOneOrderAndOrderItem(Integer uid, Integer oid) {
    //   /// //List<Order> orders = queryOrderByUid(uid);
    //    LambdaQueryWrapper<Order> lwq = new LambdaQueryWrapper<>();
    //    lwq.eq(Order::getOid,oid);
    //    Order order = orderDao.selectOne(lwq);
    //    List<OrderVo> orderVos = queryOrderItemByOid(oid);
    //    return orderVos;
    //}

    @Override
    public List<OrderVo> queryOrderInfoByStatus(Integer status) {
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Order::getStatus, status); // 比较status
        List<Order> orderList = orderDao.selectList(lqw); // 注意：不能提取orderVo，要用以下方式提取数据。
        // 转换数据
        List<OrderVo> orders = orderList.stream()
                .map(order -> BeanCopyUtils.copyBean(order, OrderVo.class))
                .collect(Collectors.toList());
        return orders;
    }

    @Override
    public void sendGoods(Integer oid, Integer expressId, String expressName) {
        // 根据oid获取一条订单信息
        Order order = orderDao.selectById(oid);
        // 填充字段
        order.setExpressId(expressId);
        order.setExpressName(expressName);
        // 修改状态为(已发货)
        order.setStatus(7); // 7: 已发货
        // 更新数据
        int rows = orderDao.updateById(order);
        if(rows != 1) {
            throw new UpdateException("更新异常");
        }
    }

    @Override
    public void refund(Integer oid, String refundReason) {
        // 根据oid获取一条订单信息
        Order order = orderDao.selectById(oid);
        // 填充退款原因字段
        order.setRefundReason(refundReason);
        // 修改状态为已发货待退款。
        order.setStatus(8);
        // 更新数据
        int rows = orderDao.updateById(order);
        if(rows != 1) {
            throw new UpdateException("更新异常");
        }
    }

    @Override
    public void examineRefundInfo(Integer oid) {
        Order order = orderDao.selectById(oid);
        // 数据库记录退款信息
        refundInfoClient.createrRefundByOrder(oid, order.getRefundReason());
        // 修改订单状态
        order.setStatus(5); // 5：已退款
        // 更新数据
        int rows = orderDao.updateById(order);
        if(rows != 1) {
            throw new UpdateException("更新异常");
        }
    }

    @Override
    public void rejectRefund(Integer oid, String reason) {
        Order order = orderDao.selectById(oid);
        order.setRejectReason(reason);
        order.setStatus(11); // 11: 拒绝
        // 更新数据
        int rows = orderDao.updateById(order);
        if(rows != 1) {
            throw new UpdateException("更新异常");
        }
    }

    @Override
    public void deleteOrder(Integer oid) {
        // 物理删除
        int rows = orderDao.deleteById(oid);
        // 根据oid,获取所有orderItem
        LambdaQueryWrapper<OrderItem> lqw = new LambdaQueryWrapper();
        lqw.eq(OrderItem::getOid, oid);
        List<OrderItem> orderItems = orderItemDao.selectList(lqw);
        for (OrderItem orderItem : orderItems) {
            int rows2 = orderItemDao.deleteById(orderItem.getId());
            if(rows2!=1) {
                throw new DeleteException("订单项删除异常");
            }
        }

        if(rows!=1) {
            throw new DeleteException("订单删除异常");
        }
    }

    @Override
    public void finishOrder(Integer oid) {
        Order order = orderDao.selectById(oid);
        // 修改订单状态
        order.setStatus(4); // 4：已完成
        // 更新数据
        int rows = orderDao.updateById(order);
        if(rows != 1) {
            throw new UpdateException("更新异常");
        }
    }

    @Override
    public void commentOrder(Integer oid, String comment) {
        Order order = orderDao.selectById(oid);
        // 设置订单评价信息
        order.setComment(comment);
        order.setStatus(10); // 10: 已评价
        // 更新数据
        int rows = orderDao.updateById(order);
        if(rows != 1) {
            throw new UpdateException("更新异常");
        }
    }

    @Override
    public IPage<Receive> conQueryAllReceiveInfo(Integer currentPage, Integer pageSize, Order order) {
        IPage page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Order> lwq=new LambdaQueryWrapper<>();
        lwq.eq(!Objects.isNull(order.getOid()), Order::getOid, order.getOid());
        lwq.eq(!Objects.isNull(order.getUid()), Order::getUid, order.getUid());
        orderDao.selectPage(page,lwq);
        return page;
    }


}
